
    /**  
    * @Title: AuthorizationListener.java
    * @Package com.efast.cafe.commponent.es.socketio.auth
    * @Description: TODO(用一句话描述该文件做什么)
    * @author Administrator
    * @date 2018年10月30日
    * @version V1.0  
    */
    
package com.efast.cafe.commponent.es.socketio.auth;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.Topic;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.corundumstudio.socketio.HandshakeData;
import com.efast.cafe.commponent.es.socketio.listener.DisSocketConnectListener;
import com.efast.cafe.commponent.es.socketio.listener.MessageDelegate;
import com.efast.cafe.commponent.es.socketio.listener.PushMessageDelegateListenerImpl;
import com.efast.cafe.commponent.es.socketio.util.SocketEventUtils;
import com.efast.cafe.commponent.es.socketio.util.SocketIOUtil;
import com.efast.cafe.commponent.log.ext.CafeLogger;
import com.efast.cafe.commponent.log.ext.CafeLoggerFactory;
import com.efast.cafe.framework.constant.FrameConstant;
import com.efast.cafe.framework.spring.SpringContextUtils;
import com.efast.cafe.util.StringUtil;

/**
    * @ClassName: AuthorizationListener
    * @Description: websocket长连接安全拦截
    * @author xuanming.feng
    * @date 2018年10月30日
    *
    */

public class AuthorizationListener implements com.corundumstudio.socketio.AuthorizationListener {

	CafeLogger logger = CafeLoggerFactory.getLogger(getClass());
	
	private static final String PARAM_TOKEN="token";
	
	private StringRedisTemplate redisTemplate;
	
	
	
	public boolean isAuthorized(HandshakeData data) {
		String sid = data.getSingleUrlParam(PARAM_TOKEN);
		if(StringUtil.isEmpty(sid)){
			logger.warn("Connect socket.io server error:Invalid authorization.");
			return false;
		}
		try{
			redisTemplate = SpringContextUtils.getBean(StringRedisTemplate.class);
			ValueOperations<String, String> ops = redisTemplate.opsForValue();
			if(!redisTemplate.hasKey(FrameConstant.SOCKET_IO_TEMP_TOKEN+sid)){
				logger.warn("Connect socket.io server error:Invalid token.");
				return false;
			}
			String authInfo = ops.get(FrameConstant.SOCKET_IO_TEMP_TOKEN+sid);
			redisTemplate.delete(FrameConstant.SOCKET_IO_TEMP_TOKEN+sid);
			
		
			createContainer(authInfo);
			List<String> info = new ArrayList<>();
			info.add(authInfo);
			data.getUrlParams().put(FrameConstant.SOCKET_UID, info);
			return true;
		}catch(Exception e){
			logger.error("Connect socket.io server error:", e);
		}
		return false;
	}
	
	
	
	private void createContainer(String uid){
		
		MessageDelegate myListener = new PushMessageDelegateListenerImpl();
		MessageListenerAdapter myAdapter = new MessageListenerAdapter();
		myAdapter.setDelegate(myListener);
		myAdapter.setDefaultListenerMethod("handleMessage");
		myAdapter.setSerializer(new StringRedisSerializer());
		myAdapter.afterPropertiesSet();
		RedisMessageListenerContainer container = new RedisMessageListenerContainer();
		container.setBeanName(SocketIOUtil.REDIS_MESSAGE_LISTENER_BEANNAME_PRE + uid);
		Topic channel = new ChannelTopic(SocketIOUtil.SOCKET_MESSAGE_KEY_ + uid);
		
		JedisConnectionFactory connectionFactory = SpringContextUtils.getBean(JedisConnectionFactory.class);
		container.setConnectionFactory(connectionFactory);
		container.addMessageListener(myAdapter, channel);
		container.afterPropertiesSet();
		container.start();

		SocketIOUtil.putMessageListener(uid, container);
	}
}
